<template>
    <el-dialog v-model="visible" :title="title" @close="cancel" :close-on-click-modal="false" width="90%">
        <div v-loading="loading" style="display: flex;">
            <el-form ref="dataFormRef" :model="dataForm" :rules="dataRules" label-width="120px" style="width: 74%;padding-right:10px;">
                <el-form-item label="关联的子栏目：" prop="categoryId">
                    <el-tree-select v-model="dataForm.categoryId" @change="treeSelectChange" :data="optindata" :render-after-expand="false" class="inp-width" />
                </el-form-item>
                <el-form-item label="定时发布：" prop="publishTime">
                    <el-date-picker v-model="dataForm.publishTime" :disabled="allContentDisabled" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" />
                </el-form-item>
                <el-form-item label="定时撤销：" prop="cancellationTime">
                    <el-date-picker v-model="dataForm.cancellationTime" :disabled="allContentDisabled" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" />
                </el-form-item>
                <el-form-item label="排序： " prop="sort">
                    <el-input-number v-model="dataForm.sort" :min="0" :disabled="allContentDisabled" />
                </el-form-item>
                <!-- <el-form-item label="关键词" prop="keyword">
                    <el-select v-model="dataForm.keyword" multiple style="width: 50%;">
                        <el-option v-for="item in keywordList" :key="item.id" :label="item.value" :value="item.value" />
                    </el-select>
                </el-form-item> -->
                <el-form-item label="日期：" prop="customDate">
                    <el-date-picker v-model="dataForm.customDate" type="date" value-format="YYYY-MM-DD" style="width: 100%;" />
                </el-form-item>
                <el-form-item label=" " prop="isAnnouncement">
                    <el-checkbox v-model="dataForm.isAnnouncement" label="上公告" border />
                </el-form-item>
                <div v-show="[1900,1902].includes(dataForm.categoryId)">
                    <el-form-item label=" " prop="isHome">
                        <el-checkbox v-model="dataForm.isHome" label="上首页" border :disabled="disabledHome" />
                    </el-form-item>
                </div>
                <el-form-item v-show="[1,2,6,10,11,15].includes(radioType)" label="选择展示图片" prop="">
                    <div style="width: 100px;height: 100px;border: 1px solid #ccc;cursor: pointer;" @click="selectImage">
                        <img v-if="dataForm.imageUrl" :src="dataForm.imageUrl" alt="" style="width: 100px;height: 100px;">
                    </div>
                </el-form-item>
                <el-form-item label="跳转链接：" prop="href">
                    <el-input v-model="dataForm.href" style="width: 100%;"></el-input>
                </el-form-item>
                <!-- 列表 -->
                <div v-show="[1,11].includes(radioType)">
                    <el-form-item label="标题名称：" prop="title">
                        <el-input v-model="dataForm.title" style="width: 100%;"></el-input>
                    </el-form-item>
                    <el-form-item label="内容来源：" prop="source">
                        <el-input v-model="dataForm.source" class="inp-width"></el-input>
                    </el-form-item>
                </div>
                <!-- 图文、图片、视频、可持续发展报告 -->
                <div v-show="[3,4,5,13].includes(radioType)">
                    <el-form-item label="文字描述：" prop="linkTitle">
                        <el-input v-model="dataForm.linkTitle" style="width: 100%;"></el-input>
                    </el-form-item>
                </div>
                <!-- 楷模 -->
                <div v-show="[6,15].includes(radioType)">
                    <el-form-item label="标题名称：" prop="title">
                        <el-input v-model="dataForm.title" style="width: 100%;"></el-input>
                    </el-form-item>
                </div>
                <!-- 董事会/高管也就是管理团队 -->
                <div v-show="[7,9].includes(radioType)">
                    <el-form-item label="名称：" prop="title">
                        <el-input v-model="dataForm.title" style="width: 100%;"></el-input>
                    </el-form-item>
                    <el-form-item label="职务：" prop="linkTitle">
                        <el-input v-model="dataForm.linkTitle" style="width: 100%;"></el-input>
                    </el-form-item>
                </div>
                <!-- 主要荣誉 -->
                <div v-show="[8].includes(radioType)">
                    <el-form-item label="名称：" prop="title">
                        <el-input v-model="dataForm.title" style="width: 100%;"></el-input>
                    </el-form-item>
                </div>
                <!-- 出版物 -->
                <div v-show="[10].includes(radioType)">
                    <el-form-item label="名称：" prop="title">
                        <el-input v-model="dataForm.title" style="width: 100%;"></el-input>
                    </el-form-item>
                </div>
                <!-- 可持续发展报告-->
                <div v-show="[13].includes(radioType)">
                    <el-form-item label="上传PDF：" prop="imageUrl">
                        <el-upload :action="uploadApi" :headers="uploadHeaders" :show-file-list="false" :on-success="(res) => handleSuccess(res, index)">
                            <el-button type="primary" :loading="fileLoading" @click="fileLoading=true">上传</el-button>
                        </el-upload>
                    </el-form-item>
                </div>
                <!-- 上传图片或视频 -->
                <div v-if="[3,4,5,6,7,8,9,10,15].includes(radioType)">
                    <el-form-item label=" ">
                        <el-upload class="avatar-uploader" :action="uploadApi2" :headers="uploadHeaders" :show-file-list="false" :on-success="(res) => handleSuccess(res, index)">
                            <img v-if="[3,4,6,7,8,9,10,15].includes(radioType)&&dataForm.imageUrl" :src="dataForm.imageUrl" class="avatar" />
                            <video v-else-if="radioType==5&&dataForm.imageUrl" controls class="avatar">
                                <source :src="dataForm.imageUrl" type="video/mp4">
                            </video>
                            <el-icon v-else class="avatar-uploader-icon">
                                <Plus />
                            </el-icon>
                        </el-upload>
                    </el-form-item>
                </div>
                <!-- 富文本编辑器 -->
                <div v-if="[1,2,6,10,11,15].includes(radioType)&& showEditor" style="border: 1px solid #ccc;margin: 0 26px 10px 26px;">
                    <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
                    <Editor style="height: 500px; overflow-y: hidden;" v-model="dataForm.content" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" @onChange="handleEditorChange" @customPaste="handleCustomPaste" />
                </div>
            </el-form>
            <div style="width: 34%;border-left: 1px solid #ccc;padding:0 10px;">
                <!-- 版本1 -->
                <!-- <div v-for="item in resultList" :key="item.id" style="margin-top: 10px;font-size: 16px;display: flex;justify-content: space-between;">
                    <div @click="scrollToError(item)" style="cursor: pointer;">
                        {{ item.errMsg }}：{{ item.errWord }}
                        <span v-if="item.corWord.length>0">——>{{ item.corWord[0] }}</span>
                    </div>
                    <el-button type="primary" v-if="item.corWord.length>0" @click="replace(item)">替换</el-button>
                </div> -->
                <!-- 版本2 -->
                <div v-for="(item,index) in resultList" :key="item.id" style="margin-top: 10px;font-size: 16px;display: flex;justify-content: space-between;">
                    <div @click="scrollToError(item)" style="cursor: pointer;">
                        {{ item.newFirstLabelName }}：{{ item.cur }}
                        <span v-if="item.correct">——>{{ item.correct }}</span>
                    </div>
                    <el-button type="primary" v-if="item.action==2" @click="acceptModify(item,index)">替换</el-button>
                    <el-button type="primary" @click="Ignore(item,index)">忽略</el-button>
                </div>
            </div>
        </div>
        <template #footer>
            <el-button @click="cancel()">取消</el-button>
            <el-button type="primary" @click="manuscriptReview()">文稿审核</el-button>
            <el-button type="primary" @click="submit()">保存</el-button>
            <!-- <el-button type="primary" v-if="checkStatus||[4,5].includes(radioType.value)" @click="submit()">{{ dataForm.publishTime?'定时发布':'保存' }}</el-button> -->

        </template>
    </el-dialog>
    <checkResult ref="checkResultRef" />
    <ysOCR ref="ysOcrRef" @displace="displace" />
    <imgListDialog ref="imgListRef" :listImg="imgList" @selectImgOk="selectImgOk" />

</template>

<script setup lang="ts">
import { reactive, ref, shallowRef, watch, onBeforeUnmount, nextTick } from 'vue'
import { ElMessage } from 'element-plus/es'
import { allColumn, saveContent, check, keywordListContent, listColumn } from '@/api/allApi' //接口
import { treeSelect } from '@/utils/myMethod' //工具类
import '@wangeditor/editor/dist/css/style.css' //富文本编辑器引入样式
import { Editor, Toolbar } from '@wangeditor/editor-for-vue' //富文本编辑器引入
import { IEditorConfig } from '@wangeditor/editor' //富文本编辑器的
import cache from '@/utils/cache' //为了获取token
import checkResult from './checkResult.vue'
import imgListDialog from './imgListDialog.vue'

const emit = defineEmits(['resetList']) //子组件调父组件方法
const checkResultRef = ref()

const visible = ref(false)
const title = ref('新增')
const loading = ref(false)
const dialogType = ref('add') //弹窗类型
const rowDate = reactive({}) //行数据
const checkStatus = ref(false) //审核状态
const disabledHome = ref(true) //上首页禁用
const oneImg = ref(false) //如果选择自己上传图片，就不从富文本里获取
const dataFormRef = ref()
const dataForm = reactive({
	title: '',
	templateType: null,
	categoryId: '',
	source: '',
	linkTitle: '',
	imageUrl: '',
	content: '',
	sort: '',
	//publishType: 0,
	//publishTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
	publishTime: '',
	cancellationTime: '',
	customDate: '',
	keyword: [],
	isAnnouncement: false,
	isHome: false,
	href: ''
})
const dataRules = reactive({
	categoryId: [{ required: true, message: '请输入子栏目', trigger: 'change' }]
}) //表单验证
const optindata = reactive([] as any[]) //关联栏目列表
const radioType = ref(0)
const allContentDisabled = ref(false)
// const imgTextList = reactive([{ imageUrl: '', linkTitle: '' }]) //图文列表
const uploadApi = ref(import.meta.env.VITE_API_URL + '/content/upload') //富文本上传
const uploadApi2 = ref(import.meta.env.VITE_API_URL + '/sys/file/upload?access_token=' + localStorage.getItem('maToken')) //单独上传
const uploadHeaders = reactive({
	Accept: 'application/json, text/plain, */*',
	Authorization: cache.getToken()
}) //上传图片请求头

//弹窗初始化
const init = (type: string, row: any) => {
	visible.value = true
	dialogType.value = type
	getList()
	getKeywordList()
	Object.assign(rowDate, row) //浅拷贝，将row赋值给rowDate，用以前直接=赋值的形式会报错
	if (type === 'add') {
		title.value = '新增'
	} else if (type == 'edit') {
		title.value = '编辑'
		//回显
		nextTick(() => {
			//估计是接口异步的事，第一次打开弹窗获取不到optindata，就走不了treeSelectChange，所以用watch监听到了再走
			watch(optindata, newVal => {
				if (newVal.length > 0 && title.value == '编辑') {
					treeSelectChange(row.categoryId)
					for (let key in dataForm) {
						dataForm[key] = row[key]
						dataForm.isAnnouncement = row.isAnnouncement == '1' ? true : false
						dataForm.isHome = row.isHome == '1' ? true : false
					}
					dataForm.keyword = row.keyword ? row.keyword.split(',') : ''
					dataForm.content = cleanHtmlContent(row.content)

					// dataForm.content = row.content
				} else {
					radioType.value = null
				}
			})
		})
	}
}
//监听imageUrl变化，无值时禁用上首页
watch(
	() => dataForm.imageUrl,
	newVal => {
		if (newVal) {
			disabledHome.value = false
		} else {
			disabledHome.value = true
			dataForm.isHome = false
		}
	}
)
//获取栏目
const getList = () => {
	listColumn({
		websiteId: Number(localStorage.getItem('WebsiteId')),
		pageNum: 1,
		pageSize: 1000
	}).then((res: any) => {
		if (res.code === 0) {
			//添加树选择器必要节点
			let arr = treeSelect(res.data.list, 'name', 'id')
			getDisable(arr)
			//用push的方法可以解决reactive定义的数组不能直接被赋值的问题，也可以选择包一层，或者用ref定义.value是可以的
			optindata.length = 0
			optindata.push(...arr)
		} else {
			ElMessage.error(res.msg)
		}
	})
	// allColumn({ websiteId: Number(localStorage.getItem('WebsiteId')) }).then((res: any) => {
	// 	if (res.code === 0) {
	// 		//添加树选择器必要节点
	// 		let arr = treeSelect(res.data, 'name', 'id')
	// 		getDisable(arr)
	// 		//用push的方法可以解决reactive定义的数组不能直接被赋值的问题，也可以选择包一层，或者用ref定义.value是可以的
	// 		optindata.length = 0
	// 		optindata.push(...arr)
	// 	} else {
	// 		ElMessage.error(res.msg)
	// 	}
	// })
}
//添加禁用
const getDisable = (array: any) => {
	for (let i = 0; i < array.length; i++) {
		const e = array[i]
		//只有叶子结点不禁用
		if (e.children && e.children.length > 0) {
			e.disabled = true
			getDisable(e.children)
		}
	}
	return array
}
// 添加一个控制编辑器显示的状态
const showEditor = ref(true)
//树选择器(关联子栏目)change事件
const treeSelectChange = (val: any) => {
	// radioType.value = null //清空模板类型的值
	radioType.value = 0 //重置radioType，让模板类型表单项消失（templateType为1时用的）
	//递归函数，栏目是树形
	const getType = (array: any) => {
		for (let i of array) {
			//找到选中的栏目（要是方法参数回来的是当前选中的对象就不用这么写了）
			if (i.id == val) {
				radioType.value = i.templateType

				// 先隐藏编辑器
				showEditor.value = false
				// 安全销毁
				if (editorRef.value) {
					try {
						editorRef.value.destroy()
					} catch (error) {
						console.log('编辑器销毁错误:', error)
					}
					editorRef.value = null
				}
				// 在下一次DOM更新后重新显示
				nextTick(() => {
					showEditor.value = true
					// 只在新增模式下清空内容，编辑模式保留回显内容
					if (dialogType.value === 'add') {
						dataForm.content = ''
					}
				})
			}
			if (i.children && i.children.length > 0) {
				getType(i.children)
			}
		}
	}
	getType(optindata)
}

const keywordList = ref([])
const getKeywordList = () => {
	keywordListContent({ websiteId: Number(localStorage.getItem('WebsiteId')) }).then((res: any) => {
		if (res.code == 0) {
			keywordList.value = res.data
		}
	})
}

//富文本编辑器相关
const editorRef = shallowRef() // 编辑器实例，必须用 shallowRef
const mode = 'default' // 或 'simple'
import { computed } from 'vue'
// 使用计算属性
const toolbarConfig = computed(() => {
	const baseKeys = ['uploadImage', 'insertTable', 'uploadVideo', 'insertLink', 'justifyLeft', 'justifyRight', 'justifyCenter', 'uploadAttachment']
	// 时政要闻有字体大小颜色等按钮，怕报社上传内容有啥规定啥的
	if (dataForm.categoryId == 1900) {
		return {
			toolbarKeys: [...baseKeys, 'bold', 'underline', 'italic', 'color', 'bgColor', 'fontSize', 'fontFamily', 'lineHeight']
		}
	}

	return { toolbarKeys: baseKeys }
})
const editorConfig: Partial<IEditorConfig> = {
	MENU_CONF: {
		// 自定义加粗样式
		// bold: {
		// 	style: 'font-weight: 600'
		// },
		// 配置 HTML 处理
		codeSelect: {
			// 允许的标签 - 确保包含 img
			allowedTags: ['p', 'img', 'br', 'table', 'tr', 'td'],
			// 允许的属性 - 确保包含图片相关属性
			allowedAttributes: {
				'*': ['style', 'class', 'src', 'alt', 'title', 'width', 'height'],
				p: ['style'],
				// div: ['style'],
				span: ['style', 'color'],
				img: ['src', 'alt', 'style', 'width', 'height', 'data-href', 'class']
			}
		}
	},
	// 添加这些配置来允许外部图片
	hoverbarKeys: {
		img: {
			menuKeys: ['viewImage', 'downloadImage', 'editImage', 'viewImageLink', 'imageWidth30', 'imageWidth50', 'imageWidth100']
		}
	},
	// 允许粘贴图片
	pasteIgnoreImg: false,
	// 自定义图片校验
	customCheckImage: (src: string, alt: string, href: string) => {
		// 放宽图片校验，允许所有图片
		return true
	}
}
const handleCustomPaste = (editor, event) => {
	// 阻止默认粘贴行为
	event.preventDefault()

	// 获取HTML内容
	const html = event.clipboardData?.getData('text/html') || ''

	if (html) {
		// 清理HTML但保留表格
		const cleanedHtml = cleanPastedHtml(html)
		editor.dangerouslyInsertHtml(cleanedHtml)
	}
}
// HTML清理函数 - 保留表格但去除样式
const cleanPastedHtml = (html: string): string => {
	// 先移除所有样式属性
	let cleaned = html.replace(/ style="[^"]*"/g, '')

	// 移除所有class属性
	cleaned = cleaned.replace(/ class="[^"]*"/g, '')

	// 移除font标签，保留内容
	cleaned = cleaned.replace(/<font[^>]*>/g, '')
	cleaned = cleaned.replace(/<\/font>/g, '')

	// 转换标题为段落
	cleaned = cleaned.replace(/<h[1-6][^>]*>/g, '<p>')
	cleaned = cleaned.replace(/<\/h[1-6]>/g, '</p>')

	// 移除span标签，保留内容
	cleaned = cleaned.replace(/<span[^>]*>/g, '')
	cleaned = cleaned.replace(/<\/span>/g, '')

	// 转换div为段落（不在表格内的）
	cleaned = cleaned.replace(/<div([^>]*)>(?!(?:[^<]*<table|\/table>))*?<\/div>/g, '<p$1></p>')

	return cleaned
}

//富文本编辑器配置图片相关
editorConfig.MENU_CONF['uploadImage'] = {
	server: uploadApi.value,
	fieldName: 'file',
	//自定义请求头，获取token
	headers: uploadHeaders,
	// 设置最大文件大小（单位：字节）
	maxFileSize: 100 * 1024 * 1024, // 100MB
	allowedFileTypes: ['*'], // 允许所有文件类型
	// 自定义文件大小超出限制的错误提示
	// onFailed(file: File, res: any) {
	// 	if (res && res.error && res.error.indexOf('max file size') > -1) {
	// 		ElMessage.error('文件大小不能超过10MB')
	// 	}
	// },
	onBeforeUpload(file: File) {
		loading.value = true
		return file
	},
	// 单个文件上传成功之后
	onSuccess(file: File, res: any) {
		loading.value = false
	}
}
//富文本编辑器配置视频相关
editorConfig.MENU_CONF['uploadVideo'] = {
	server: uploadApi.value,
	fieldName: 'file',
	//自定义请求头，获取token
	headers: uploadHeaders,
	maxFileSize: 20 * 1024 * 1024 * 1024, // 20GB
	onBeforeUpload(file: File) {
		loading.value = true
		return file
	},
	// 单个文件上传成功之后
	onSuccess(file: File, res: any) {
		loading.value = false
	}
}

//富文本编辑器方法
const handleCreated = editor => {
	editorRef.value = editor // 记录 editor 实例，重要！
	nextTick(() => {
		if (dialogType.value === 'edit' && dataForm.content) {
			// 先用setHtml尝试
			editor.setHtml(dataForm.content)

			// 如果不行，取消注释下面这行
			// editor.dangerouslyInsertHtml(dataForm.content);
		}
	})
}

const fileLoading = ref(false)
//文件上传成功回调
const handleSuccess = (res: any, index: number) => {
	// imgTextList[index].imageUrl = res.data.url
	dataForm.imageUrl = res.data.url
	fileLoading.value = false
	oneImg.value = true
}

const resultList = reactive([])
//文稿审核
// 版本1
// const manuscriptReview = () => {
// 	loading.value = true
// 	let content = new DOMParser().parseFromString(dataForm.content, 'text/html').body.textContent //获取纯文本
// 	check({ content: content }).then((res: any) => {
// 		loading.value = false
// 		if (res.code === 0) {
// 			if (JSON.parse(res.data).code == 1) {
// 				let returnParam = JSON.parse(res.data).result[0].content
// 				console.log(JSON.parse(res.data), 'JSON.parse(res.data)')

// 				checkStatus.value = true
// 				if (returnParam.length > 0) {
// 					// let contentRed = content
// 					resultList.length = 0
// 					// 存储所有需要标红的字符串
// 					const toHighlight = []
// 					for (let e of returnParam) {
// 						resultList.push(e)
// 						if (dataForm.content?.includes(e.errWord) && e.errWord !== '') {
// 							// 收集需要标红的字符串
// 							toHighlight.push(e.errWord)
// 						}
// 					}
// 					// 最后一次性替换所有目标字符串，进行标红
// 					if (toHighlight.length > 0) {
// 						// 创建一个正则表达式，匹配所有需要标红的字符串
// 						const regex = new RegExp(toHighlight.map(escapeRegExp).join('|'), 'g')
// 						//replace可以用正则表达式进行匹配
// 						dataForm.content = dataForm.content.replace(regex, match => {
// 							//每匹配成功走一遍这个，不改变原字符串，只是把匹配到的字符串用<span>标签包裹起来
// 							return `<span style="color: red;">${match}</span>`
// 						})
// 					}
// 					// 辅助函数：转义正则表达式中的特殊字符
// 					function escapeRegExp(string) {
// 						return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
// 					}
// 					editorRef.value.setHtml(dataForm.content)
// 					editorRef.value.history.clear() // 清空操作历史

// 					// checkResultRef.value.init(content, JSON.parse(res.data).data.adviceList)
// 				} else {
// 					ElMessage.success('审核通过')
// 				}
// 			}
// 		} else {
// 			ElMessage.success(res.msg)
// 		}
// 	})
// }
// 版本2
const manuscriptReview = () => {
	loading.value = true
	let content = new DOMParser().parseFromString(dataForm.content, 'text/html').body.textContent //获取纯文本
	check({ content: content }).then((res: any) => {
		// let res = {
		// 	code: 0,
		// 	msg: 'success',
		// 	data: '{"code":0,"msg":"成功","data":{"html":"<html>\\n <head></head>\\n <body>\\n  <p audit-paragraph=\\"0\\">我<span id=\\"audit-0c8d35b68ea643bb88332c86515be8e1\\" data-advice-tag-id=\\"advice-fd6e01463e39433db07bea77855cbba2\\">胎头</span>看向天空，她也<span id=\\"audit-a00f70560ac44ce7ac371dd79d416281\\" data-advice-tag-id=\\"advice-0704290f7ae44dc0951cec0ad340266e\\">胎头</span>看<span id=\\"audit-939398769b5d490a807929eb84780186\\" data-advice-tag-id=\\"advice-c2de40db0bfa4a9c9fd8e994417683db\\">蓝蓝的天</span>。</p>\\n </body>\\n</html>","adviceList":[{"cur":"胎头","correct":"抬头","firstLabel":601,"firstLabelName":"语法性差错","secondLabel":601008,"secondLabelName":"多字漏字","adviceTagId":"advice-fd6e01463e39433db07bea77855cbba2","action":2,"actionName":"替换","actionView":"建议替换","keyWordLocationList":[{"keyWord":"胎头","id":"audit-0c8d35b68ea643bb88332c86515be8e1"}],"dataType":5,"detectionType":0,"sentence":"我胎头看向天空，她也胎头看蓝蓝的天。","label":60,"labelName":"深度审校","newFirstLabel":601,"newFirstLabelName":"语法性差错","operateType":2,"operateTypeView":"设为正词","type":0,"angle":0.0},{"cur":"胎头","correct":"抬头","firstLabel":601,"firstLabelName":"语法性差错","secondLabel":601008,"secondLabelName":"多字漏字","adviceTagId":"advice-0704290f7ae44dc0951cec0ad340266e","action":2,"actionName":"替换","actionView":"建议替换","keyWordLocationList":[{"keyWord":"胎头","id":"audit-a00f70560ac44ce7ac371dd79d416281"}],"dataType":5,"detectionType":0,"sentence":"我胎头看向天空，她也胎头看蓝蓝的天。","label":60,"labelName":"深度审校","newFirstLabel":601,"newFirstLabelName":"语法性差错","operateType":2,"operateTypeView":"设为正词","type":0,"angle":0.0},{"cur":"蓝蓝的天","correct":"蓝天","firstLabel":601,"firstLabelName":"语法性差错","secondLabel":601006,"secondLabelName":"语句不通","adviceTagId":"advice-c2de40db0bfa4a9c9fd8e994417683db","action":2,"actionName":"替换","actionView":"建议替换","keyWordLocationList":[{"keyWord":"蓝蓝的天","id":"audit-939398769b5d490a807929eb84780186"}],"dataType":5,"detectionType":0,"sentence":"我胎头看向天空，她也胎头看蓝蓝的天。","label":60,"labelName":"深度审校","newFirstLabel":601,"newFirstLabelName":"语法性差错","operateType":2,"operateTypeView":"设为正词","type":0,"angle":0.0}],"openId":"4460f6c757b54ac084d74b4d9f27c15b","wordsNum":18,"status":2,"statusName":"审核成功"}}'
		// }
		loading.value = false
		if (res.code === 0) {
			if (JSON.parse(res.data).code == 0) {
				let returnParam = JSON.parse(res.data).data
				console.log('校验json结果', returnParam)

				checkStatus.value = true
				if (returnParam.adviceList.length > 0) {
					resultList.length = 0
					let content = dataForm.content
					const tempMarkers = [] // 存储临时标记和对应项
					// 第一次遍历：用临时标记替换所有错误
					returnParam.adviceList.forEach((item: any, index: number) => {
						resultList.push(item)
						const marker = `__ERROR_${index}__` // 生成唯一标记，如 __ERROR_0__
						tempMarkers.push({ marker, item })
						content = content.replace(item.cur, marker) // 只替换第一个匹配项
						//替换后："我__ERROR_0__看向天空，她也__ERROR_1__看蓝蓝的天。"
					})
					// 第二次遍历：用高亮span替换临时标记
					tempMarkers.forEach(({ marker, item }) => {
						const span = `<span style="color: red;">${item.cur}</span>`
						content = content.replace(marker, span)
					})
					dataForm.content = content
				} else {
					ElMessage.success('审核通过')
				}
			}
		} else {
			ElMessage.success(res.msg)
		}
	})
}
//替换
//版本1
// const replace = (item: any) => {
// 	// 使用 RegExp 构造函数，并转义特殊字符
// 	const escapedCur = `<span style="color: red;">${item.errWord}</span>`.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
// 	const regex = new RegExp(escapedCur, 'g')
// 	if (dataForm.content?.includes(item.errWord) && item.errWord !== '') {
// 		dataForm.content = dataForm.content.replace(regex, item.corWord[0])
// 		editorRef.value.setHtml(dataForm.content)
// 		editorRef.value.history.clear() // 清空操作历史

// 		const tempList = resultList.filter(j => j.errPos !== item.errPos)
// 		resultList.splice(0, resultList.length, ...tempList)
// 	}
// }
//版本2
const acceptModify = (item: any, index: number) => {
	let span = `<span style="color: red;">${item.cur}</span>`
	dataForm.content = dataForm.content.replace(span, item.correct)
	// 从结果列表中移除
	resultList.splice(index, 1)
}
//忽略
const Ignore = (item: any, index: number) => {
	let span = `<span style="color: red;">${item.cur}</span>`
	dataForm.content = dataForm.content.replace(span, item.cur)
	// 从结果列表中移除该项
	resultList.splice(index, 1)
	ElMessage.success('已忽略该建议')
}

// 辅助函数：转义正则表达式中的特殊字符
function escapeRegExp(string) {
	return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}

// 滚动到错误位置
const scrollToError = (item: any) => {
	// if (!editorRef.value || !item.errWord) return
	if (!editorRef.value || !item.cur) return

	// 获取编辑器实例
	const editor = editorRef.value
	// 获取编辑器DOM容器
	const editorContainer = editor.getEditableContainer()

	// 在富文本内容中查找错误文本的位置
	const content = editor.getHtml()
	const tempDiv = document.createElement('div')
	tempDiv.innerHTML = content

	// 查找所有包含错误文本的元素
	const elements = tempDiv.querySelectorAll('*')
	let targetElement: HTMLElement | null = null

	elements.forEach(el => {
		// if (el.textContent?.includes(item.errWord)) {
		if (el.textContent?.includes(item.cur)) {
			targetElement = el as HTMLElement
		}
	})

	if (targetElement) {
		// 在真实编辑器中找到对应的元素
		const editorElements = editorContainer.querySelectorAll('*')
		let realTarget: HTMLElement | null = null

		editorElements.forEach(el => {
			// if (el.textContent?.includes(item.errWord)) {
			if (el.textContent?.includes(item.cur)) {
				realTarget = el as HTMLElement
			}
		})

		if (realTarget) {
			// 滚动到目标元素
			realTarget.scrollIntoView({
				behavior: 'smooth',
				block: 'center'
			})

			// 添加高亮效果（可选）
			realTarget.style.backgroundColor = 'rgba(255, 255, 0, 0.3)'
			setTimeout(() => {
				realTarget!.style.backgroundColor = ''
			}, 2000)
		}
	}
}
//保存
const submit = () => {
	dataFormRef.value.validate((valid: boolean) => {
		if (valid) {
			let obj = {
				...dataForm,
				isAnnouncement: dataForm.isAnnouncement ? '1' : '0',
				isHome: dataForm.isHome ? '1' : '0',
				// isAnnouncement: JSON.stringify({
				// 	isAnnouncement: dataForm.isAnnouncement ? '1' : '0',
				// 	websiteId: Number(localStorage.getItem('WebsiteId'))
				// }),
				// isHome: JSON.stringify({
				// 	isHome: dataForm.isHome ? '1' : '0',
				// 	websiteId: Number(localStorage.getItem('WebsiteId'))
				// }),
				keyword: dataForm.keyword ? dataForm.keyword.join(',') : '',
				templateType: radioType.value,
				tenantId: JSON.parse(localStorage.getItem('userInfo')).id, //租户id
				websiteId: Number(localStorage.getItem('WebsiteId')) //网站id
			}
			if (dialogType.value === 'edit') {
				obj.id = rowDate.id
			}

			saveContent([obj]).then((res: any) => {
				if (res.code === 0) {
					ElMessage.success('操作成功')
					emit('resetList')
					cancel()
				} else {
					ElMessage.success(res.msg)
				}
			})
		}
	})
	// location.reload()
}
//取消重置
const cancel = () => {
	visible.value = false
	radioType.value = 0
	resultList.length = 0
	// imgTextList.length = 0
	// imgTextList[0] = { imageUrl: '', linkTitle: '' }
	checkStatus.value = false
	dataForm.imageUrl = ''
	dataForm.content = '' //不知道为啥用resetFields()方法没有清空富文本编辑器内容
	dataFormRef.value.resetFields()
}

// 清理 HTML 内容的函数,老数据与富文本不匹配，需要替换成一致状态
function cleanHtmlContent(html) {
	if (!html) return ''

	try {
		let cleaned = html.replace(/\\"/g, '"').replace(/\\\\/g, '\\')
		cleaned = cleaned.replace(
			/<div[^>]*style\s*=\s*["'][^"']*text-align\s*:\s*center[^"']*["'][^>]*>\s*<img([^>]+)>\s*<\/div>/gi,
			'<p style="text-align: center;"><img$1></p>'
		)

		// 匹配任何 div 包裹的 img（更通用的替换）
		cleaned = cleaned.replace(/<div[^>]*>\s*<img([^>]+)>\s*<\/div>/gi, '<p><img$1></p>')

		// 处理图片说明文字的结构（旧数据中图片后面的 span 结构）
		// 将图片和说明文字整合
		cleaned = cleaned.replace(
			/(<p[^>]*><img[^>]+><\/p>)\s*<span[^>]*>\s*<div>\s*<p[^>]*>([^<]*)<\/p>\s*<\/div>\s*<\/span>/gi,
			'$1<p style="text-align: center; font-size: 12px; color: #003399;">$2</p>'
		)

		// 你的现有清理逻辑
		cleaned = cleaned.replace(/<span[^>]*>(\s*<div[^>]*>)/g, '$1')
		cleaned = cleaned.replace(/(<\/div>\s*)<\/span>/g, '$1')

		return cleaned
	} catch (error) {
		return html.replace(/\\"/g, '"').replace(/\\\\/g, '\\')
	}
}

const imgList = ref([] as any[]) //图片列表
// 添加单独的 onChange 事件处理函数
const handleEditorChange = (editor: IDomEditor) => {
	// 获取最新的 HTML 内容
	const html = editor.getHtml()

	// 提取图片路径并更新到 dataForm.imageUrls
	const imageUrls = extractImageUrls(html)
	// 更新图片列表
	imgList.value = imageUrls.map(url => url)

	// 如果需要，也可以在这里更新 dataForm.content
	dataForm.content = html
}
// 提取富文本中所有图片路径的函数
const extractImageUrls = (html: string): string[] => {
	if (!html) return []

	const parser = new DOMParser()
	const doc = parser.parseFromString(html, 'text/html')
	const imgElements = doc.querySelectorAll('img')

	const urls: string[] = []
	imgElements.forEach(img => {
		const src = img.getAttribute('src')
		if (src) {
			urls.push(src)
		}
	})

	return urls
}

const imgListRef = ref()
// 选择图片
const selectImage = () => {
	// 这里可以添加选择图片的逻辑
	// 例如，打开文件选择器
	// 选择完成后，将图片路径添加到 imgList.value
	// 并更新 dataForm.content 中的图片路径
	imgListRef.value.init(dataForm.imageUrl)
}
const selectImgOk = url => {
	dataForm.imageUrl = url
}

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
	const editor = editorRef.value
	if (editor == null) return
	editor.destroy()
})
defineExpose({
	init
})
</script>
<style lang="scss" scoped>
.inp-width {
	width: 220px;
}
.el-radio.is-bordered.el-radio--large {
	height: auto;
}
::v-deep(.avatar-uploader .el-upload) {
	border: 2px dashed #d9d9d9;
	border-radius: 6px;
	cursor: pointer;
	position: relative;
	overflow: hidden;
}
::v-deep(.avatar-uploader .el-upload:hover) {
	border-color: #409eff;
}
::v-deep(.avatar-uploader-icon) {
	font-size: 28px;
	color: #8c939d;
	width: 150px;
	height: 150px;
	line-height: 150px;
	text-align: center;
}
::v-deep(.avatar) {
	width: 150px;
	height: 150px;
	display: block;
}

::v-deep(.btn-primary) {
	color: #fff;
	background-color: #409eff;
	height: 32px;
	line-height: 32px;
	border-radius: 2px;
}
</style>
